package com.hammera.common.baseUI

import android.accounts.NetworkErrorException
import android.app.Activity
import android.content.Context
import com.hammera.common.baseRx.HFlatMap
import com.hammera.common.baseRx.HSubscriber
import com.zzh.base.BaseModel
import com.zzh.base.baseRx.RxManager
import io.reactivex.Flowable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.functions.Function
import java.net.ConnectException
import java.net.SocketTimeoutException
import java.util.concurrent.TimeUnit
import java.util.concurrent.TimeoutException


abstract class BasePresenter<M : BaseModel<*>, V : BaseView> {
    protected var mRxManage = RxManager()
    protected var mContext: Context? = null
    protected var mActivity: Activity? = null
    protected var mModel: M? = null
    protected var mView: V? = null
    fun setMV(m: M?, v: V?) {
        this.mModel = m
        this.mView = v
    }

    fun setContext(context: Context?) {
        mContext = context?.applicationContext ?: context
    }


    fun setActivity(context: Activity?) {
        mActivity = context
    }

    fun onDestroy() {
        mActivity = null
        mRxManage.clear()
    }

    fun rxClear(){
        mRxManage.clear()
    }

    fun <T, R> toSubscribe(observable: Flowable<T>?, flatMap: HFlatMap<T, R>, observer: HSubscriber<R>) {
        observable?.flatMap { result -> Flowable.just(flatMap.apply(result)) }
                ?.subscribeOn(io.reactivex.schedulers.Schedulers.io())    // 指定subscribe()发生在IO线程
                ?.observeOn(AndroidSchedulers.mainThread())  // 指定Subscriber的回调发生在io线程
                ?.timeout(30, TimeUnit.SECONDS)    //重连间隔时间
//                ?.retry(3)
                ?.retryWhen(object : Function<Flowable<Throwable>, Flowable<*>> {

                    private var mRetryCount: Int = 0

                    @Throws(Exception::class)
                    override fun apply(throwableObservable: Flowable<Throwable>): Flowable<*> {



                        return throwableObservable.flatMap { throwable ->
                            if (throwable is NetworkErrorException
                                    || throwable is ConnectException
                                    || throwable is SocketTimeoutException
                                    || throwable is TimeoutException) {

                            }
                            mRetryCount++
                            if (mRetryCount <= 3)
                                Flowable.timer(3000, TimeUnit.MILLISECONDS)
                            else
                                Flowable.error<Any>(throwable)
                        }
                    }
                })
                ?.subscribe(observer)

        mRxManage.add(observer)   //订阅
    }

    fun <T> toSubscribe(observable: Flowable<T>?, observer: HSubscriber<T>) {
        observable?.subscribeOn(io.reactivex.schedulers.Schedulers.io())    // 指定subscribe()发生在IO线程
                ?.observeOn(AndroidSchedulers.mainThread())  // 指定Subscriber的回调发生在io线程
                ?.timeout(30, TimeUnit.SECONDS)    //重连间隔时间
//                ?.retry(3)
                ?.retryWhen(object : Function<Flowable<Throwable>, Flowable<*>> {

                    private var mRetryCount: Int = 0

                    @Throws(Exception::class)
                    override fun apply(throwableObservable: Flowable<Throwable>): Flowable<*> {
                        return throwableObservable.flatMap { throwable ->
                            if (throwable is NetworkErrorException
                                    || throwable is ConnectException
                                    || throwable is SocketTimeoutException
                                    || throwable is TimeoutException) {
                                mRetryCount++
                                if (mRetryCount <= 3)
                                    Flowable.timer(3000, TimeUnit.MILLISECONDS)
                                else
                                    Flowable.error<Any>(throwable)

                            } else {
                                Flowable.error<Any>(throwable)
                            }
                        }
                    }
                })
                ?.subscribe(observer)

        mRxManage.add(observer)   //订阅
    }

}